package com.pi4axe.component;

import org.axe.extra.abc_thread.SerialExecutor;
import org.axe.extra.abc_thread.TaskPack;
import org.axe.extra.abc_thread.TaskPackBusController;
import org.axe.helper.ioc.BeanHelper;
import org.axe.util.LogUtil;

import com.pi4axe.component.callback.SerialDataReceiveCallback;
import com.pi4axe.manager.SerialManager;
import com.pi4j.io.serial.Baud;
import com.pi4j.io.serial.SerialDataEvent;

/**
 * 使用串口的PN532，拨码器默认00，HSU模式
 */
public class PN532SerialPort {
	// 不能按照pi4j的github例子，获取默认端口
	private String serialPort = "/dev/ttyAMA0";
	private OnDataReceiveCallBack callBack = null;

	private Long sendDataTime = 0l;
	private Long asckDataTime = 0l;

	public interface OnDataReceiveCallBack {
		public void onReceiveData(String UID);
	}

	public PN532SerialPort(OnDataReceiveCallBack callBack) throws Exception {
		this.callBack = callBack;
		initSerialPort();

		// 添加读卡任务
		TaskPackBusController tbc = BeanHelper.getBean(TaskPackBusController.class);
		if (tbc != null) {
			tbc.start();
			tbc.addTaskPack(new TaskPack("PN532SerialPort.readCard") {
				@Override
				public boolean task(SerialExecutor serialexecutor) {
					try {
						//记录发送读卡命令时间
						synchronized (PN532SerialPort.this.sendDataTime) {
							PN532SerialPort.this.sendDataTime = System.currentTimeMillis();
						}
						
						// 读卡
						String[] split = "00 00 FF 04 FC D4 4A 01 00 E1 00".split(" ");
						byte[] cmdData = new byte[split.length];
						for (int i = 0; i < cmdData.length; i++) {
							cmdData[i] = (byte) Integer.parseInt(split[i], 16);
						}
						SerialManager.sendData(serialPort, cmdData);
						
						try {
							Thread.sleep(500);// 500毫秒如果还没应答，那就是费了
						} catch (Exception e) {
						}
						synchronized (PN532SerialPort.this.asckDataTime) {
							if (PN532SerialPort.this.asckDataTime <= PN532SerialPort.this.sendDataTime) {
								// 废了，没有应答，重新初始化读卡器试试
								try {
									SerialManager.release("/dev/ttyAMA0");
									Thread.sleep(300);
									PN532SerialPort.this.initSerialPort();// 重新初始化
								} catch (Exception e) {
									LogUtil.error(e);
								}
							}
						}
					} catch (Exception e) {
						
					}
					
					return true;
				}
			});
		}
	}

	private void initSerialPort() throws Exception {
		// 初始化串口
		SerialManager.initSerial(serialPort, Baud._115200, new SerialDataReceiveCallback() {
			@Override
			public void onReceiveData(SerialDataEvent dataEvent) {
				try {
					synchronized (asckDataTime) {
						asckDataTime = System.currentTimeMillis();
					}
					String data = dataEvent.getHexByteString();
					if (data.startsWith("00,00,FF,00,FF,00,00,00,FF,0C")) {
						String[] split = data.split(",");
						if (split.length > 22 && split[14].equals("01")) {// 找到一张卡
							String UID = split[19] + split[20] + split[21] + split[22];
							callBack.onReceiveData(UID);
						}
					} else {
						if (data.equals("00,00,FF,00,FF,00,00,00,FF,02,FE,D5,15,16,00")) {
							// 初始化成功，被唤醒
							LogUtil.log("PN532 init success");
						} else {
							// LogUtil.log("NFC UNKNOWN CODE:" + data);
						}
					}
				} catch (Exception e) {
				}
			}

			@Override
			public String callbackName() {
				return serialPort + "-callback";
			}
		});

		// 激活读卡器
		String[] split = "55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 03 fd d4 14 01 17 00".split(" ");
		byte[] data = new byte[split.length];
		for (int i = 0; i < data.length; i++) {
			data[i] = (byte) Integer.parseInt(split[i], 16);
		}
		SerialManager.sendData(serialPort, data);
	}

}
